"""
Serial Read and Write

Usage : Read or write data from sink serial
Author: HanBing
Update: ChenQi 
Date  : 2010-10-11
"""

import serial, threading, time, binascii
import socket

sinkDataList = []
sinkData = ''
tmplist = []
data_len = 0

def ReadSinkData():
    """
        Get data from sink serial
        @param: None
        @return: one piece of sink data or ""
    """
    global sinkData
    result = ''
    if len(sinkData):
        result = sinkData
        sinkData = ''
    else:
        #print "[in serialrw.py]no data"
        time.sleep(2)
    return result

def GetSinkSerialPort():
    """
        Get Sink Serial Port from sinkserialport file
        @param: None
        @return: return the port
    """
    return FileReader()
def ClearData():
    global sinkDataList
    global tmplist
    global data_len
    sinkDataList = []
    tmplist = []
    data_len = 0

#-----------------Beginning of the Class Definition!!!--------------------------#
class SerialRW:
    def __init__(self):
        """
            Initialize variables and start to read data from serial
            @param: None
            @return: None
        """
        self.ss = None
        self.ss_alive = False
        #self.start()
    
    def start(self):
        """
            Open Sink Serial or GPRS Serial
            @param: None
            @return: None
        """
        self.OpenSinkSerial()
        #self.OpenGPRSSerial()

    def OpenSinkSerial(self):
        """
            Open Sink Serial and Create a thread to read data from Sink Serial
            @param: None
            @return: None
        """
        try :
            self.ss = serial.Serial(GetSinkSerialPort(), 115200)
            self.ss.open()
            if self.ss.isOpen():
                print '[Info in SerialRW:] ss is open!'
                self.ss_alive = True
                self.ss_thread = None
                self.ss_thread = threading.Thread(target = SinkSerialReader, args = (self.ss, self.ss_alive))
                print '[Info in SerialRW:] success to create ss thread!'
                self.ss_thread.start()
        except Exception, ex :
            print '[!!Error in SerialRW:] fail to open ss!'

            
    def SinkSerialWriter(self, payload):
        """
            Send or Write data to sink serial
            @param: The data which will be sent to sink serial
            @return: True to False
        """
        try:
            if self.ss_alive :
                self.ss.write(payload)
                print '---'
                print ''.join(['\\x%02x' % ord(x) for x in payload])
                print 'serial write'
                return True
            else :
                self.ss = serial.Serial(GetSinkSerialPort(), 115200)
                self.ss.open()
                if self.ss.isOpen() :
                    self.ss_alive = True
                    self.ss.write(payload)
                    print '[Info in SerialRW:] write to sink finished!'
                    print 'serial write'
                    return True
                else :
                    return False
        except Exception, ex:
            print '[!!Error in SerialRW:] fail to open ss!'
  
    def stop(self) :
        """
            Close the serials which are open
            @param: None
            @return: None
        """
        self.ss_alive = False
        self.ss_thread.join()
        if self.ss.isOpen() :
            self.ss.close()
            
#---------------End of the Class Definition!!!--------------------------------------#
         
def SinkSerialReader(ss, ss_alive):
    """
        Read data from Sink Serial
        @param: the status of sink serial
        @return: sink data list
    """
    global sinkData
    buff = ''
    while ss_alive :
        try :
            rawData = ''         
            n = ss.inWaiting()
            if n :
                rawData = ss.read(n)

                print 'rawData: ' + ''.join(['\\x%02x' % ord(m) for m in rawData])
                buff += rawData
                while True:
                    indexS = buff.find('\x7e\x45')
                    indexE = buff.find('\x7e', indexS + 1)
                    if indexS != -1 and indexE != -1:
                        msg = buff[indexS : indexE + 1]
                        buff = buff[:indexS] + buff[indexE + 1:]
                        if len(msg) == 20:
                            continue
                        print 'msg len:', len(msg)
                        print 'msg :' + ''.join(['\\x%02x' % ord(m) for m in msg])
                        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
                        sock.sendto(msg, ('192.168.1.232', 50001))
                        print 'send ok'
                        print '-----------------------------------------'
                        sinkData += msg
                    else:
                        break
        except Exception, ex :
            print str(ex)
            
def FileReader():
    """
        Read data from file 
        @param: None
        @return: return the data
    """
    serialport = ''
    try:
        f = open('sinkserialport')
        for l in f :
            l = l.strip()
            if l.startswith('#') :
                continue
            else :
                serialport = l
                break
        f.close()
    except ex :
        print str(ex)
    finally :
        f.close()
        print serialport
    return serialport

if __name__ == '__main__' :
    rw = SerialRW()
    rw.start()
	rw.SinkSerialWriter('\x53\x54\x41\x52\x54\x46\x35\xC2\x8F\x5B\x53\x54\x4F\x50\x46\x57\x0A\x3D\x70\x53\x54\x45\x50\x01\x47\xae\x14')
    while 1 :
        print ReadSinkData()
    rw.stop()
    print 'after stop'

